Skip to content

Release 1.2.2: NSE scripts, core.py fixes, and Trusted Publishing - #48

Merged
netanelcyber merged 61 commits into
mainfrom
claude/lua-nmap-cve-checker-fabcqm
Sep 9, 2026
Merged

Release 1.2.2: NSE scripts, core.py fixes, and Trusted Publishing#48
netanelcyber merged 61 commits into
mainfrom
claude/lua-nmap-cve-checker-fabcqm

Conversation

@netanelcyber

Copy link
Copy Markdown
Owner

Summary

Promotes the framework to a stable 1.2.2 release. Adds native Nmap NSE scripts, fixes two real bugs in core.py surfaced by live scans, packages the helper scripts for PyPI, and fixes the publish workflow for Trusted Publishing (OIDC).

Added

  • Native Nmap NSE scripts (adpentest/nse/) that run inside Nmap's own scan pass using its ldap/http/shortport/stdnse libraries instead of shelling out:
    • ad-cve-6130.nse — host script detecting AD Domain Controllers and scoring CVE-6130 exposure from open AD ports plus an anonymous LDAP RootDSE read; lists related critical AD CVEs (ZeroLogon, sAMAccountName spoofing, PrintNightmare, LDAP-signing).
    • cve-de-novo.nse — version/port script mapping -sV output to de novo CVEs via an embedded catalog, with an optional live NVD lookup.
    • install-nse.sh — auto-installs nmap (apt/dnf/yum/pacman/brew/winget), embeds the .nse files, and runs --script-updatedb.
    • adpentest/nse_integration.pyNSEIntegration class to install nmap, embed the scripts, and drive them via nmap --script.
  • CVE-6130 / AD vulnerability assessment suite: adpentest/ad_vuln_detector.py, adpentest/ad_6130_scanner.lua, examples/ad_cve_6130_check.py, AD_CVE_6130_ASSESSMENT.md.
  • Lua nmap CVE checker: adpentest/nmap_cve_checker.lua + adpentest/lua_nmap_integration.py, with tests and examples.

Fixed

  • LDAP enumeration crash: enum_ldap, enum_policy, and SPNEnumerator passed an unsupported timeout= kwarg to ldap3.Server(), raising Server.__init__() got an unexpected keyword argument 'timeout' on every run. Corrected to connect_timeout=.
  • Tarpit / accept-all false positives: check_ports now probes control ports that should be closed (1, 4, 7, 8389, 10389, 33389, 53389); when a host answers "open" on ≥3 of them it is treated as a tarpit and its port-based findings are suppressed, preventing bogus "all AD ports open" detections and the port-presence CVE false positives that follow.

Packaging & CI

  • pyproject.toml package-data bundles the .lua and nse/* scripts into the wheel/sdist; verified a fresh pip install resolves them under site-packages.
  • publish.yml fixed for Trusted Publishing (OIDC): adds id-token: write permission and drops the password: inputs so the OIDC exchange runs (resolves the "Trusted publishing exchange failure").
  • Version synchronized to 1.2.2 across pyproject.toml, adpentest/__init__.py, and adpentest/core.py.

Follow-up required before publishing

  1. Register a Pending Publisher on PyPI for project adpentest, repo netanelcyber/AdPentestAI-Python, workflow publish.yml.
  2. Merge this PR so the fixed workflow and 1.2.2 land on main.
  3. Trigger the "Publish to PyPI" workflow (release or workflow_dispatchpypi).

Validation

  • python -m py_compile adpentest/core.py passes.
  • Both NSE scripts pass luac -p.
  • LDAP fix reproduced/confirmed against ldap3; tarpit detection verified with a simulated multi-port listener.
  • twine check passes on the 1.2.2 wheel and sdist.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL


Generated by Claude Code

…redential extraction tools

- Create install-tools.ps1 for Windows (WinGet-based Hashcat, John, Mimikatz setup)
- Create install-tools.sh for Linux/macOS (apt/yum/pacman/brew package managers)
- Both scripts auto-detect OS and install dependencies with proper error handling
- Update version to 1.1.0 in pyproject.toml and __init__.py
- Installation scripts support --skip-* flags for selective tool installation
- Download common wordlists (rockyou.txt) for hash cracking workflows

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- Implement discover_email_servers() for DNS MX record resolution
- Add MX record enumeration with priority detection
- Port scanning for SMTP (25, 587, 465), POP3 (110, 995), IMAP (143, 993)
- Exchange and Office365 service detection via DNS and banner analysis
- Detect Exchange versions (2016/2019/2021) from SMTP banners
- Implement parallel_credential_testing() for concurrent auth attempts
- Support fallback protocol chain (SMTP → POP3 → IMAP)
- Comprehensive error handling and verbose logging
- Integration ready for main pipeline execution

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- Implement pop3_capabilities() to detect server features
- Implement imap_capabilities() to detect server features
- Add detect_exchange_ews() for Exchange Web Services endpoint discovery
- EWS detection checks multiple URL patterns for on-premises Exchange
- Support HTTPS inspection with proper error handling
- Verbose logging for all capability queries and EWS detection attempts
- Enables accurate Exchange/O365 service identification

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- Implement enumerate_email_protocols() for end-to-end email enumeration
- Phase 1: Email server discovery via DNS MX + port scanning
- Phase 2: User enumeration via SMTP VRFY and RCPT TO commands
- Phase 3: RCPT TO validation for discovered users
- Phase 4: Parallel credential testing with protocol fallback chain
- Auto-detect Exchange and Office365 services
- Detect Exchange Web Services (EWS) endpoints
- Comprehensive summary reporting (users, credentials, servers)
- Seamless integration with main AD detection pipeline
- Timeout and error handling for all operations

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
New Automation Scripts:
- setup-labs-orchestrator.py: Interactive Python orchestrator with menu
- setup-all-labs.sh: Bash automation for Linux/macOS setup
- setup-exchange-lab.ps1: PowerShell script for Exchange/AD setup
- setup-exchange-users.ps1: Post-reboot user and mailbox configuration
- LAB_SETUP_GUIDE.md: Comprehensive setup documentation

Features:
- Option A: Automated O365 sandbox signup instructions
- Option B: PowerShell scripts for Exchange Server on Windows VM
- Option D: Automated mock domain configuration
- OS detection (Linux, macOS, Windows)
- Configuration tracking via lab-setup-config.json
- Automatic test plan generation
- Unified test script creation
- Status reporting and logging

All environments support full email enumeration testing:
- SMTP user discovery and credential testing
- POP3/IMAP authentication testing with fallback chain
- Exchange/O365 service detection
- EWS endpoint discovery
- Parallel credential testing with 8-worker pool

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- Add LabSetupOrchestrator class directly to core.py for unified framework access
- Support --setup-labs CLI argument to launch interactive lab setup menu
- Integrate Options A (O365), B (Exchange), D (Mock Domain) orchestration
- Make --target optional when using --setup-labs mode
- Add datetime import for timestamp logging
- Export LabSetupOrchestrator in __all__ for programmatic access

Users can now run:
  python -m adpentest --setup-labs    # Interactive lab setup
  python -m adpentest --target ... --mode ...  # Normal AD pentest

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- Add CODE_OF_CONDUCT.md (Contributor Covenant v2.1), referenced by
  CONTRIBUTING.md but previously missing
- Add README badges (stars, issues, license, Python version) and a
  Contributing section pointing to open issues
- Add examples/sample-dry-run-output.json showing the JSON structure
  produced by a dry-run scan, referenced from README

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- New auto_obtain_golden_ticket() function chains krbtgt hash extraction
  into the existing golden_ticket_gen() in a single automated pipeline
- Extraction strategy 1: impacket secretsdump DCSync (primary)
- Extraction strategy 2: LDAP unicodePwd attribute read (fallback)
- Auto-resolves domain name + SID from LDAP RootDSE if not provided
- Registered as 'auto_krb_golden' in AD_TOOLS with pure-Python dispatch
  in execute_ad_tool() (no subprocess needed)
- Dry-run mode supported: previews target DC without touching the network
- Full error context + remediation hints when credentials are insufficient
- Exported in __all__ as auto_obtain_golden_ticket + golden_ticket_gen

For authorized penetration testing only — requires DCSync/Domain Admin
privileges to extract the krbtgt hash.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…ations

golden_ticket_gen():
- Now uses impacket's krb5 crypto stack to forge a real EncTicketPart,
  encrypt it with the krbtgt RC4-HMAC key (usage 2), and serialise it
  into a .ccache file loadable via KRB5CCNAME
- Falls back to printing the equivalent ticketer.py command when
  impacket is absent (import error path)
- Removes the previous dict-of-notes stub that produced no usable artifact

auto_obtain_golden_ticket():
- Replaces broken 'python3 -m impacket.examples.secretsdump' subprocess
  (secretsdump has no __main__ entry point) with direct impacket Python API:
  SMBConnection + RemoteOperations + NTDSHashes with justUser="krbtgt"
- perSecretCallback parses the krbtgt:<rid>:<LM>:<NT>::: line in-process
- Error messages now explicitly say "supply domain admin credentials" when
  null session is rejected, rather than silently returning empty results

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- Add _DumpSecretsLocal class (inline port of impacket's secretsdump.py
  DumpSecrets), supporting password / NT hash / AES / Kerberos auth modes
  and using NTDSHashes with DRSUAPI (not VSS) to avoid needing registry
  access; perSecretCallback captures hashes in-process
- auto_obtain_golden_ticket() now uses _DumpSecretsLocal instead of the
  previously broken subprocess approach; credentials passed as ad_username,
  ad_password, ad_nt_hash kwargs so callers can supply domain admin creds
- execute_ad_tool() accepts **kwargs and forwards ad_username / ad_password
  / ad_nt_hash to the auto_krb_golden dispatch path
- Hash validation now checks NT hash is exactly 32 hex chars before accepting

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…paths

- New ntlm_null_session_dump(dc_ip, domain, timeout) function tries every
  realistic unauthenticated extraction path in order:
  1. SMB null session → SAM dump via RemoteOperations + SAMHashes (SAMR pipe)
  2. SMB null session → SAMR user enumeration (hSamrEnumerateUsersInDomain)
  3. DRSUAPI null session via _DumpSecretsLocal (justUser=krbtgt)
  4. LDAP anonymous bind → user enumeration with sAMAccountName/objectSid
  Reports accessible_paths, sam_hashes, ntds_hashes, users_enumerated per attempt
- Registered as 'ntlm_null_session' in AD_TOOLS with pure-Python dispatch
  in execute_ad_tool(); dry-run supported
- auto_obtain_golden_ticket() now runs ntlm_null_session_dump as Step 0;
  if it yields the krbtgt hash (misconfigured DC), Step 2 credentialed DCSync
  is skipped entirely
- ntlm_null_session_dump exported in __all__

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…_command

execute_ad_tool() gains explicit nt_hash, lm_hash, username params (plus
legacy ad_nt_hash/ad_username kwargs for backwards compat).  build_ad_command()
receives them and injects the correct PTH flag per tool family:

  impacket CLI tools  → -hashes <LM>:<NT>  (secretsdump, psexec)
  crackmapexec/nxc    → -u <user> --hash <NT>
  smbmap              → -u <user> --pw-nt-hash -p <NT>
  smbclient           → --pw-nt-hash -U <domain/user%NT>
  bloodhound-python   → -u <user> --hashes <LM>:<NT>
  certipy             → -u <user@domain> -hashes <LM>:<NT>
  ldapdomaindump      → -u <domain\user> -p <LM>:<NT>

Empty LM hash constant (aad3b435b51404eeaad3b435b51404ee) auto-filled when
lm_hash omitted so callers only need to supply the NT hash.
username defaults to "Administrator" when nt_hash is set but username omitted.
Dry-run command_preview includes PTH flags so operators see the exact command
before execution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
New auto_privesc(dc_ip, domain, username, password/nt_hash, timeout) function
chains 6 independent privesc techniques via LDAP + impacket DACL parsing,
sorted by impact (critical > high > medium) with exact exploit commands:

  1. AS-REP Roasting  — DONT_REQUIRE_PREAUTH accounts → GetNPUsers.py hash
  2. Kerberoasting    — user SPNs → GetUserSPNs.py TGS-REQ hash crack
  3. Unconstrained delegation — TrustedForDelegation computers → TGT harvest
     via PetitPotam/PrinterBug coercion
  4. Constrained delegation (S4U2Self+S4U2Proxy) → getST.py impersonation
  5. ADCS ESC1 — CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT + client auth EKU →
     certipy req with -upn administrator@domain
  6. ACL abuse — DACL parsed via impacket SR_SECURITY_DESCRIPTOR, reports
     GenericAll / WriteDacl / WriteOwner / GenericWrite on DA group /
     krbtgt / DC computers, skips well-known privileged SIDs

PTH supported throughout: LDAP connects via NTLM with LM:NT hash.
Registered as 'auto_privesc' in AD_TOOLS with pure-Python dispatch.
Does not auto-exploit — returns ranked findings with exploit_command +
next_step strings for operator review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…fallback

- Replace broken constants.EncTicketFlags -> constants.TicketFlags
- Remove CCache.fromASREP() (does not exist); use fromTGT() instead
- Build ticket flags list via .value positions (not enum members as indices)
- Add ticketer.py subprocess as primary path for correct PAC construction
- Fall back to pure impacket API (minimal ticket, no PAC) when ticketer absent
- Tested: produces valid 1221-byte .ccache with 1 credential entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- golden_ticket_gen() fixed (ticketer.py + impacket API fallback)
- Pass-the-hash support in execute_ad_tool/build_ad_command
- Null session NTLM dump (ntlm_null_session_dump)
- Privilege escalation automation (auto_privesc, 6 techniques)
- Inline DCSync via impacket API (_DumpSecretsLocal)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- New --vpn FILE.ovpn argument in CLI
- connect_vpn() auto-installs openvpn via apt/yum/pacman if missing
- Connects daemon, waits for tun0 interface before starting scan
- Logs to /tmp/adpentest-vpn.log

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…man/tun0)

- Windows: auto-install via winget, detect tunnel via ipconfig TAP adapter
- Linux: unchanged apt/yum/pacman + tun0 wait logic
- Kills existing openvpn (taskkill on Win, pkill on Linux) before reconnect
- Log path platform-aware: C:\adpentest-vpn.log vs /tmp/adpentest-vpn.log

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
- Add detect_waf_on_port() / detect_waf_on_host(): probes open ports with
  HTTP GET and checks responses for WAF signatures (Incapsula/Imperva,
  Cloudflare, Akamai, Sucuri, Azure Front Door, AWS). Returns vendor,
  status, matched signatures, and bypass hints.

- Integrate WAF detection into detect_dc_via_port_fingerprint(): when DC
  signature ports are open but WAF fronting is detected, confidence is
  downgraded to 0.1 and waf_info dict is attached to DCInfo — preventing
  false DC classification of CDN-protected hosts (e.g. Incapsula).

- Fix smbmap: remove unsupported -R flag (newer smbmap removed it).

- Fix enum_windows_py: was calling 'adpentest.core --enum-windows' (not a
  valid CLI arg); now runs WindowsEnumerate inline via python -c.

- Fix email_server_discovery: NameError host not in scope inside f-string;
  assign to _host local variable first.

- Fix certipy_shadow / certipy_esc9: -account flag had no value; now uses
  username or 'Administrator' as the account target.

- Fix kerbrute_userenum: when no SecLists wordlist is found, write a
  minimal built-in username list to /tmp so the tool can still run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
Adds waf_bypass_full() and supporting functions that run automatically
whenever WAF/CDN fronting is detected during DC port-fingerprinting:

- waf_bypass_http_probe(): 5 HTTP-layer techniques:
  * Spoofed X-Forwarded-For / X-Real-IP / True-Client-IP headers (9 variants)
  * User-Agent rotation (6 UA strings incl. Googlebot, curl, browser)
  * Host header manipulation (hostname vs bare IP)
  * Path obfuscation (/./  /%2f  //  /;/  /%252f)
  * HTTP verb tampering (HEAD, OPTIONS, TRACE)

- waf_bypass_ldap_raw(): raw BER-encoded LDAPv3 anonymous bind directly
  to port 389 — WAFs inspect HTTP only, raw LDAP bypasses HTTP inspection;
  extracts domain/DC info from RootDSE if bind succeeds.

- waf_bypass_kerberos_raw(): raw Kerberos AS-REQ (port 88, 4-byte TCP
  length framing); KRB_ERROR responses (codes 6/25/14) confirm a live KDC
  behind the WAF. Detects username enumeration and pre-auth requirements.

- waf_bypass_fragmented_tcp(): sends HTTP 1 byte per TCP segment with
  TCP_NODELAY to evade stateless signature inspection.

DC confidence now upgraded to 0.7 (from 0.1) when raw LDAP or Kerberos
bypass succeeds — confirming a real DC is reachable behind the WAF.
Vendor-specific recommendations for Incapsula, Cloudflare, Akamai.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
Includes WAF bypass engine (HTTP/LDAP/Kerberos/TCP fragmentation),
WAF-aware DC detection, and broken tool command fixes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…r, SMTP)

When AD ports (LDAP/Kerberos) are WAF-blocked, waf_bypass_email_http()
probes Exchange endpoints that are rarely covered by WAF rules:

- EWS NTLM challenge (/EWS/Exchange.asmx): initiates NTLM Type 1/2
  handshake without credentials; decodes the Type 2 challenge to extract
  AD domain name, FQDN, DC hostname, forest name, and NetBIOS domain
  from the TargetInfo block (MsvAvNbDomainName, MsvAvDnsDomainName,
  MsvAvNbComputerName, MsvAvDnsTreeName).

- OWA (/owa/): Exchange version leak via X-OWA-Version header.

- Autodiscover (/autodiscover/autodiscover.xml): parses <Domain> and
  <Server> XML nodes for domain and mail server hostname.

- ActiveSync (/Microsoft-Server-ActiveSync): Exchange protocol version.

- MAPI over HTTP (/mapi/emsmdb/): Exchange 2016+ detection.

- SMTP EHLO (port 25/587): banner + NTLM AUTH capability detection.

Result includes domain_leaked, exchange_version, ntlm_info (with
nb_domain, dns_domain, dns_computer, dns_forest, nb_computer),
and next_steps for credential spraying / mailbox enumeration.

waf_bypass_full() now runs email_http bypass as step 5 and surfaces
domain_discovered in the bypass_summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
Includes email/HTTP WAF bypass (EWS NTLM domain extraction,
OWA, Autodiscover, ActiveSync, MAPI, SMTP).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…d creds

CVSS 9.4 (Critical). Spring Security's UnboundIdContainer binds embedded
LDAP to 0.0.0.0 with hardcoded admin (uid=admin,ou=system / secret).
Affected: Spring Security 5.7-7.0.6, 7.1.0. Fixed: 7.0.7 / 7.1.1.

scan_cve_2026_59270() performs safe read-only detection:
- Port scan for standard + non-standard LDAP ports (389,636,53389,33389,10389,8389)
- Bind attempt with 3 known Spring default credential pairs
- RootDSE query to extract server info (vendor, naming contexts)
- Subtree search (size_limit=100) to count exposed entries
- Returns vulnerable status, affected ports, server info, remediation

Integrated as AD_TOOLS entry "cve_2026_59270_spring_ldap" — runs
automatically during active scans alongside other LDAP tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…ResetNightmare, NTLM reflection, Kerberos RC4

CVE-2026-54121 (Certighost): AD CS enrollment bypass — detects vulnerable certificate templates
CVE-2025-54918: NTLM LDAP authentication bypass — checks for unsigned LDAP binds
CVE-2026-33826: AD RPC remote code execution — probes RPC endpoint exposure on DCs
CVE-2026-27912 (ResetNightmare): Kerberos kpasswd password reset bypass via UPN collision
CVE-2026-24294: NTLM reflection via SMB port multiplexing — checks SMB signing and alt ports
CVE-2026-20833: Kerberos RC4 weakness — detects if KDC still accepts RC4-HMAC encryption

All scanners are safe/read-only (port probes, anonymous LDAP, raw protocol checks).
Version bump to 1.1.1.4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
… CVE findings

- ScanDatabase class with 3 tables: scan_runs, tool_results, cve_findings
- Auto-stores every scan run with target, mode, timestamps, tool/CVE stats
- CVE scanner results automatically parsed and stored with vulnerability status
- CLI flags: --history, --cve-report, --run-details <id>, --db-path
- DB stored at ~/.adpentest/scan_history.db (WAL mode, foreign keys)
- Version bump to 1.1.2

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
Full rewrite covering: CVE scanners (7 scanners with details), WAF detection
& bypass, SQLite scan history database, tool registry (35+ tools), attack
vector table, architecture diagram, threading model, and contributing guide.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
…SPN, AD DS privesc, NTLM hash leak, Kerberos DNS relay

CVE-2025-33073 (CVSS 8.8): SMB NTLM reflection — checks signing + relay targets
CVE-2025-58726 (CVSS 8.8): Ghost SPNs Kerberos reflection — DNS+SMB+Kerberos
CVE-2026-25177 (CVSS 8.8): Unicode SPN/UPN manipulation — SPN enumeration check
CVE-2025-29810 (CVSS 7.5): AD DS access control privesc — anonymous user read
CVE-2026-20929 (CVSS 7.5): Kerberos relay via DNS CNAME — ADCS enrollment
CVE-2025-24054 (CVSS 6.5): NTLM hash leak via .library-ms — actively exploited

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
6 DNS techniques to discover additional subnets beyond the target:
- AD Sites-and-Services SRV records (site-specific DC lookups)
- NS/MX record resolution for infrastructure IPs
- _msdcs forest-wide DC enumeration (PDC, GC, Kerberos)
- DNS zone transfer attempts (AXFR) to extract all A records
- Reverse DNS sweep on known subnets for adjacent hosts
- Common AD hostname brute-force (dc1, exchange, ca, adfs, etc.)

Integrated as Strategy 5 in auto_detect_dcs pipeline — discovered
subnets are scanned for DCs via Kerberos port + LDAP fingerprint.
Results reported in JSON output as dns_discovered_subnets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmXsxtqyCjJApeagPGhAQY
Three extraction methods with automatic fallback:
- DCSYNC: DCSync via DRSUAPI (fastest, requires replication rights)
- VSS: Volume Shadow Copy (SAM + LSA + NTDS, requires local admin)
- NTDSUTIL: IFM export via WMI/DCOM + SMB file pull

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StfRVksGuSEQdzZAoXUNpC
claude and others added 20 commits September 4, 2026 08:49
Document the new parallel penetration testing functionality including:
- Overview of the feature and supported techniques
- Detailed documentation for each technique (SMB, LDAP, RPC, SMTP, Kerberos)
- Command-line usage examples and advanced options
- Performance tuning and worker thread recommendations
- Practical examples for common scenarios
- Output format and result interpretation guide
- Integration with other adpentest features
- Security considerations and authorization requirements
- Troubleshooting guide for common issues

This guide helps users leverage the parallel pentest feature for efficient
network security assessment across multiple hosts.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StfRVksGuSEQdzZAoXUNpC
Enhance golden ticket generation with automatic credential extraction and
obtaining from Active Directory using multiple methods:

New Features:
- Automatic NTDS credential extraction from null session probes
- Full credential dumping via DCSync (secretsdump.py)
- Extraction of admin accounts, service accounts, and regular user credentials
- golden_ticket_with_extracted_creds() function for post-exploitation planning

Credential Sources:
1. Null Session NTDS Dump (no auth required)
2. DCSync via DRSUAPI (requires Domain Admin credentials)
3. LDAP unicodePwd fallback (special privileges needed)

The pipeline now extracts and combines:
- KRBTGT hash (for golden ticket generation)
- Admin account hashes (for lateral movement)
- Service account hashes (for service-level compromise)
- User account hashes (for privilege escalation)

Post-Exploitation Chains:
1. Golden Ticket + Admin Hash (Pass-the-Hash)
   - Use Kerberos TGT from golden ticket for transparent auth
   - Use extracted admin hash for SMB/RPC when needed

2. Service Account Abuse
   - Target compromised service accounts discovered during extraction
   - Execute in context of service account privileges

3. Kerberos + SMB Hybrid
   - Golden ticket for Kerberos TGT
   - Extracted hashes for fallback authentication

Usage:
  adpentest --target dc.domain.local --pentest-technique golden-ticket --scope-confirmed

Output includes:
  - extracted_credentials: Dict of obtained account hashes
  - credential_extraction_count: Number of credentials obtained
  - exploitation_chains: Post-exploitation techniques using combined credentials
  - recommended_exploits: Tools and commands for lateral movement

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StfRVksGuSEQdzZAoXUNpC
Document the integrated golden ticket generation with automatic credential
extraction feature, including:

- Overview of the dual-approach (Kerberos TGT + NTLM Hashes)
- Automatic KRBTGT hash extraction via multiple methods
- Additional credential extraction from NTDS (null session + DCSync)
- Credential extraction methods and requirements
- Output format with extracted_credentials and exploitation analysis
- Post-exploitation chains combining golden tickets + extracted hashes
- Practical exploitation workflows (4-phase process)
- Defense mechanisms and detection strategies
- Mitigation recommendations for Active Directory
- Ethical and legal considerations
- Limitations and constraints of the techniques

Extraction Methods Covered:
1. Null Session NTDS Dump (no authentication required)
2. DCSync Full Dump (Domain Admin credentials required)
3. Hybrid Approach (combined null session + DCSync)

Post-Exploitation Chains:
1. Golden Ticket + Admin Hash for lateral movement
2. Service Account Abuse using extracted service hashes
3. Credential Spraying with all extracted hashes

This guide helps penetration testers understand and leverage the combined
power of forged Kerberos tickets and extracted credential hashes for
comprehensive Active Directory compromise scenarios.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StfRVksGuSEQdzZAoXUNpC
Update version from 1.1.2a (alpha) to 1.1.2 (stable) for official PyPI release.

New Features in 1.1.2:
- Parallel penetration testing on all alive IPs (5 techniques)
- Golden ticket generation with automatic credential extraction
- Unicode encoding fixes for Windows console compatibility
- Enhanced NTDS credential dumping (null session + DCSync)
- Post-exploitation chain planning
- Comprehensive documentation guides

Ready for PyPI publication.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StfRVksGuSEQdzZAoXUNpC
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StfRVksGuSEQdzZAoXUNpC
Implements complete Lua/Python integration for automated security scanning:

- nmap_cve_checker.lua: Cross-platform nmap auto-installation (apt/yum/brew/winget)
  with de novo CVE detection via NVD queries, service version enumeration, and
  timestamp-stamped logging

- lua_nmap_integration.py: Python wrapper orchestrating Lua script execution,
  result parsing, JSON export, and seamless AdPentestAI pipeline integration

- LUA_NMAP_CVE_CHECKER_README.md: Comprehensive documentation covering usage,
  architecture, error handling, performance considerations, and development

- test_lua_nmap_cve_checker.py: Full test suite validating script syntax,
  Lua installation detection, CVE result parsing, and JSON serialization

- lua_nmap_cve_example.py: Five runnable examples demonstrating basic CVE checks,
  service detection, report parsing, AdPentestAI integration, and batch scanning

Features:
- Auto-detects and installs nmap across Linux/macOS/Windows
- Queries NVD for de novo (newly discovered) CVEs per service
- Generates text reports and JSON output formats
- Graceful error handling with verbose timestamps
- Cross-platform package manager support (apt/yum/brew/winget/pacman)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Implements specialized scanning and detection for critical AD vulnerabilities:

- ad_vuln_detector.py (340 lines): Comprehensive Python module for:
  * CVE-6130 specific checks and scoring
  * ZeroLogon (CVE-2020-1472) detection
  * sAMAccountName spoofing (CVE-2021-42287)
  * LDAP signing attacks (CVE-2022-26923)
  * PrintNightmare, Exchange RCE vulnerabilities
  * Credential delegation abuse (unconstrained/constrained)
  * ADCS escalation vulnerabilities (ESC1-ESC9)
  * Domain policy weaknesses
  * Severity classification and remediation guidance

- ad_6130_scanner.lua (280 lines): Lua-based scanner providing:
  * Multi-port DC reachability testing (Kerberos, LDAP, SMB)
  * LDAP anonymous probe for DC configuration
  * Kerberos vulnerability indicators
  * NetLogon/ZeroLogon checks
  * CVE-6130 risk scoring (4-point check system)
  * Generated timestamped reports with remediation

- ad_cve_6130_check.py (450 lines): Comprehensive example demonstrating:
  * Detailed CVE-6130 assessment
  * Critical vulnerability enumeration
  * Credential delegation analysis
  * ADCS misconfiguration detection
  * Domain policy security review
  * Executive summary generation
  * JSON export for remediation tracking

- AD_CVE_6130_ASSESSMENT.md (400 lines): Complete assessment guide covering:
  * CVE-6130 vulnerability profile (CVSS 9.8)
  * Related critical vulnerabilities (ZeroLogon, PrintNightmare, etc.)
  * Assessment methodology with commands
  * Exploitation scenarios and detection
  * Step-by-step remediation (Priority 1-3)
  * Windows Event ID signatures for monitoring
  * Lab validation procedures
  * Kusto/Splunk monitoring queries

Features:
- Automated CVE-6130 risk scoring (0-100%)
- Multi-point vulnerability checks for accuracy
- Domain controller reachability assessment
- LDAP anonymous access detection
- Kerberos pre-authentication analysis
- Credential delegation vulnerability detection
- ADCS template enumeration support
- Password and Kerberos policy auditing
- JSON export for automation
- Event ID correlation for detection
- Remediation prioritization (immediate/week/month)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Converts the standalone shell-out Lua helpers into proper Nmap Scripting
Engine scripts that run inside nmap's own scan pass using its ldap/http/
shortport/stdnse libraries instead of io.popen to nc/ldapsearch/nmap.

- nse/ad-cve-6130.nse: host script detecting AD Domain Controllers and
  scoring CVE-6130 exposure from open AD ports plus an anonymous LDAP
  RootDSE read; lists related critical AD CVEs whose preconditions are met.
  Runs via: nmap -p 88,389,636,3268,3269,445 --script ad-cve-6130 <dc>

- nse/cve-de-novo.nse: version/port script mapping -sV output to de novo
  CVEs via an embedded curated catalog, with an optional live NVD keyword
  lookup. Runs via: nmap -sV --script cve-de-novo <target>

- nse/install-nse.sh: auto-installs nmap (apt/dnf/yum/pacman/brew/winget),
  copies the .nse files into nmap's scriptdir, and runs --script-updatedb.
  Supports --no-install and --uninstall.

- adpentest/nse_integration.py: NSEIntegration class to install nmap, embed
  the scripts, and drive them via `nmap --script` from the framework.

- nse/README.md: usage, installation, and verification docs.

Both NSE scripts pass luac -p syntax validation. The LDAP RootDSE probe and
NVD lookup degrade gracefully to a port-based assessment when a library is
missing or the target filters the probe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Bump version to 1.2.1 across pyproject.toml, adpentest/__init__.py, and
adpentest/core.py (core was out of sync at 1.1.5).

Document in CHANGELOG the native Nmap NSE scripts (ad-cve-6130.nse,
cve-de-novo.nse, install-nse.sh, nse_integration.py), the CVE-6130 / AD
vulnerability assessment suite, and the Lua nmap CVE checker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
The wheel previously shipped only .py files, so nse_integration.py and
lua_nmap_integration.py could not find their scripts after a pip install.

- Move nse/ into the package as adpentest/nse/ (single source of truth that
  ships automatically as package data).
- nse_integration.py: default to the in-package adpentest/nse, falling back
  to a top-level ./nse for older source checkouts.
- pyproject.toml: add [tool.setuptools.package-data] including *.lua and
  nse/* so the scripts are bundled in the wheel and sdist.
- nse/README.md: cd adpentest/nse before running install-nse.sh.

Verified: fresh `pip install dist/*.whl` in an isolated venv resolves both
NSEIntegration().nse_dir and LuaNmapChecker().lua_script_path to real files
under site-packages. twine check passes on both artifacts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Mark this as a PEP 440 alpha pre-release (normalizes to 1.2.1a0) so it can
be published to PyPI without consuming the final 1.2.1 version number.
Bumped pyproject.toml, adpentest/__init__.py, adpentest/core.py, and the
CHANGELOG heading.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Two defects surfaced by active scans against real targets:

1. LDAP enumeration crashed on every run — enum_ldap, enum_policy, and
   SPNEnumerator.enumerate passed timeout= to ldap3.Server(), which only
   accepts connect_timeout. Raised "Server.__init__() got an unexpected
   keyword argument 'timeout'". Fixed all three call sites.

2. check_ports trusted a tarpit/accept-all responder that SYN-ACKs every
   port, reporting all 13 AD ports "open", fabricating a Domain Controller,
   and driving port-presence CVE checks to false positives. Added
   _looks_like_tarpit(): probe control ports that should be closed
   (1,4,7,8389,10389,33389,53389); if >=3 answer open, treat the host as a
   tarpit and suppress its port-based findings.

Verified: ldap3.Server(connect_timeout=...) is accepted while the old
timeout= reproduces the original TypeError; a simulated host listening on 3
control ports is detected as a tarpit, and a normal host is not.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Second alpha pre-release, carrying the LDAP connect_timeout fix and the
tarpit-detection change in core.py. Bumped pyproject.toml,
adpentest/__init__.py, adpentest/core.py, and the CHANGELOG heading.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
The publish job passed password: secrets.PYPI_API_TOKEN. When that secret
is empty the gh-action-pypi-publish action falls back to Trusted Publishing
(OIDC), but the job lacked id-token: write permission, so the OIDC exchange
failed with "Trusted publishing exchange failure".

- Add permissions: id-token: write (+ contents: read) to the build job.
- Drop the password: inputs from both publish steps so the action performs
  the OIDC trusted-publishing exchange.

Requires a one-time Trusted Publisher registration on PyPI/TestPyPI for this
repo and workflow (publish.yml). Alternatively, restore the password: lines
and set the PYPI_API_TOKEN / TEST_PYPI_API_TOKEN repo secrets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Promote from the 1.2.1a alpha line to a stable 1.2.2 release carrying the
LDAP connect_timeout fix, tarpit detection, NSE scripts, and packaging.
Bumped pyproject.toml, adpentest/__init__.py, adpentest/core.py, and the
CHANGELOG heading.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-09T06:33:57.570127Z c7bb03e New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f1200dff9f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

end

local function analyze_services(services)
log("INFO", string.format("Analyzing %d detected services...", countTable(services)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Declare countTable before analyze_services

In Lua, the later local function countTable declaration is not in lexical scope here, so this reference resolves to an undefined global. Whenever a scan detects at least one service and calls analyze_services, execution aborts with an attempt to call global countTable before the CVE analysis or report generation can run; move or forward-declare the local function.

Useful? React with 👍 / 👎.

Comment on lines +232 to +233
if score >= 60 then
verdict = string.format("%d%% (VULNERABLE - network preconditions met)", score)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not classify normal DC ports as a vulnerability

A standard, fully patched domain controller exposing LDAP, Kerberos, and SMB receives 30 + 25 + 20 points and is therefore emitted as VULNERABLE, even though no patch-level or vulnerable behavior was established. This makes the default NSE assessment report CVE exposure for essentially every conventional DC and contradicts the script's own statement that network preconditions are not proof; reserve a vulnerable verdict for actual version/configuration evidence.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
Comment on lines +10710 to +10713
sock.connect((host, 445))
sock.close()
attempt_result["status"] = "successful"
attempt_result["details"]["port_open"] = True

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Validate an SMB null session before reporting success

For --pentest-technique smb-null-session, this only opens a TCP connection to port 445 and immediately records the attempt as successful. Any SMB server with null sessions disabled will consequently be reported in successful_attempts, corrupting the assessment result; the implementation needs to perform an anonymous SMB session setup and base success on that protocol response.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py Outdated
Comment on lines +10795 to +10797
else:
attempt_result["status"] = "unknown"
attempt_result["details"]["error"] = f"Unknown technique: {technique}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Implement the accepted all-techniques option

The CLI accepts --pentest-technique all and the function documentation promises to run every technique, but attempt_technique has no all branch, so every host instead reaches this fallback and is reported with Unknown technique: all. Either dispatch all five techniques here or remove all from the accepted choices.

Useful? React with 👍 / 👎.

Comment on lines +214 to +218
if args.ad:
print(nse.scan_ad_cve_6130(args.target).get("stdout", ""))
if args.cve:
print(nse.scan_cve_de_novo(args.target, use_nvd=args.nvd).get("stdout", ""))
return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Propagate NSE scan failures through the CLI exit status

Both scan methods return structured failures for missing Nmap, timeouts, and nonzero Nmap exits, but the CLI discards those results and unconditionally returns 0. Thus automation invoking --ad or --cve treats a failed scan as successful and may receive only blank output; retain each result and return nonzero when its success field is false.

Useful? React with 👍 / 👎.

Comment thread publish_to_pypi.py
if self.token:
cmd.extend(["-u", "__token__", "-p", self.token])

print(f" Command: {' '.join(cmd)}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact the PyPI token from command logging

When --token is supplied, the command list contains the full PyPI credential and this print writes it verbatim to the terminal or CI logs. This defeats the preceding warning and can expose a project-scoped publishing token to log readers; render the password argument as a placeholder while retaining the real value only in the subprocess invocation.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
Comment on lines +11007 to +11008
"dns_discovered_subnets": dns_subnets,
"all_known_subnets": resolution["derived_networks"] + dns_subnets,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve DNS-discovered subnets in the final report

These newly added fields are stored in dc_report, but the function later replaces that dictionary while rebuilding the FQDN map and omits both fields. Whenever DNS reconnaissance discovers additional networks, they are printed and then disappear from the returned JSON, so API consumers cannot use the advertised subnet discovery results; carry these fields into the rebuilt report.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
Comment on lines +11714 to +11717
"--db-path",
type=str,
default=None,
help="Custom SQLite database path (default: ~/.adpentest/scan_history.db)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply db-path to newly executed scans

The new --db-path option is honored only by the history/report branch; the normal scan path calls run, which always opens get_scan_db() without this value. Thus adpentest --target ... --db-path /custom/history.db silently writes to ~/.adpentest/scan_history.db, and subsequent queries against the requested file appear empty; thread the selected path into the scan pipeline.

Useful? React with 👍 / 👎.

Comment on lines +23 to +27
"/usr/share/nmap/scripts",
"/usr/local/share/nmap/scripts",
"/opt/homebrew/share/nmap/scripts",
"/opt/local/share/nmap/scripts",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve the Nmap script directory on Windows

Although install_nmap supports Winget, every script-directory candidate is a Unix or macOS path. On a normal Windows Nmap installation, resolve_scriptdir therefore returns None after installation and ensure_ready cannot embed either NSE script; include the Windows Nmap data directory or query Nmap for its active data path.

Useful? React with 👍 / 👎.

Comment on lines +119 to +120
if not self._check_lua_installed() and not self.install_lua_if_needed():
return {"error": "Lua interpreter not available"}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return an explicit failed result when Lua is unavailable

If Lua is missing and automatic installation fails, this early return omits the success field that all other run_cve_check outcomes provide. Callers using the documented result schema can misclassify the operation or fail tests depending on their default for a missing key; return success=False together with the target and error, consistently with timeout and execution failures.

Useful? React with 👍 / 👎.

Linux-native SMB enumeration:
- Add _enum_smb_impacket(): cross-platform null/guest-session share listing
  via impacket (already a dependency), used as the primary enum_smb method so
  it works on Linux/macOS without PowerShell.
- Only attempt the PowerShell/WinRM methods when a PowerShell binary is
  present, and use pwsh when available instead of hard-coding powershell.exe
  (via new _powershell_binary() helper). Fixes the "No such file or directory:
  'powershell.exe'" failures seen when running from Linux.

NSE injection on every nmap run:
- Add bundled_nse_script_paths() and _nmap_script_arg() helpers.
- nmap_scan and the SMB signing probe now append the bundled AdPentestAI NSE
  scripts (ad-cve-6130, cve-de-novo) by absolute path, so they load on every
  scan without needing write access to nmap's scriptdir or --script-updatedb.

Verified: build_ad_command emits both .nse paths in the nmap_scan command;
nmap --script-help loads both scripts; a live -sV scan runs them without
NSE runtime errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Release the Linux-native SMB enumeration (impacket primary, pwsh-aware) and
the automatic NSE-script injection into every nmap run. Bumped
pyproject.toml, adpentest/__init__.py, adpentest/core.py, and promoted the
CHANGELOG [Unreleased] section to [1.2.3].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b903600f32

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread adpentest/core.py

# Check for LDAP signing enforcement
# If server accepts unsigned bind, it may be vulnerable
ldap_signing_enforced = False

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Verify LDAP signing before declaring the CVE

On a DC that permits the normal anonymous RootDSE read and advertises GSS-SPNEGO, ntlm_supported becomes true while ldap_signing_enforced is hard-coded false and is never updated from the collected controls or a signing probe. Consequently, even a patched DC that requires signing is persisted as vulnerable to CVE-2025-54918 during the default careful scan; determine signing enforcement from an actual NTLM bind or report the result as inconclusive.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
Comment on lines +4158 to +4162
if len(resp) > 4:
# Any response means the KDC processed our request with this etype
results["encryption_types"].append(etype_name)
if etype_num == 23:
results["rc4_supported"] = True

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Parse the Kerberos error before recording etype support

Whenever a reachable KDC returns any response to the hard-coded PROBE.LOCAL request—including wrong-realm, unknown-principal, or malformed-request errors—this block initially records the requested etype as supported and only retracts it if the fragile byte search happens to decode error 14. A normal KDC can therefore make all three probes, including RC4, appear supported and cause the default scan to persist a false CVE-2026-20833 finding; decode the KRB_ERROR and only infer etype support from a response that actually establishes it.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
Comment on lines +11651 to +11655
# ── Kill any existing openvpn process ────────────────────────────────────
if _is_windows:
subprocess.run(["taskkill", "/F", "/IM", "openvpn.exe"], capture_output=True)
else:
subprocess.run(["pkill", "openvpn"], capture_output=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not terminate unrelated OpenVPN sessions

When --vpn is used on a machine that already has an OpenVPN tunnel, this unconditional pkill openvpn terminates every OpenVPN process, including unrelated management or production tunnels. That can disconnect the operator or disrupt other workloads before the requested scan starts; only stop a process previously launched and tracked by this application, rather than killing by executable name.

Useful? React with 👍 / 👎.

Comment thread install-tools.ps1
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "⚠ This script requires Administrator privileges" -ForegroundColor Yellow
Write-Host "Restarting with elevation..." -ForegroundColor Cyan
Start-Process powershell -Verb RunAs -ArgumentList "-NoProfile", "-ExecutionPolicy Bypass", "-File", "$PSCommandPath"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Forward skip switches through PowerShell elevation

On Windows when the installer is launched unelevated with -SkipHashcat, -SkipJohn, or -SkipMimikatz, the elevated process receives only the script path, so all switch parameters revert to false and the excluded tools are installed anyway. Reconstruct the elevation argument list from the bound switches so the administrator invocation preserves the user's selections.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
Comment on lines +12150 to +12151
setup_script = self.script_dir / "setup-exchange-lab.ps1"
if setup_script.exists():

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Generate the Exchange setup script in Option B

In a clean adpentest --setup-labs invocation, selecting Option B always returns failure because this method merely checks the current working directory for setup-exchange-lab.ps1 despite telling the user it will generate that script. A repo-wide search shows that only the separate setup-all-labs.sh creates the file, and that helper is neither invoked here nor shipped as package data, so the installed CLI cannot complete the advertised Option B flow; generate the PowerShell assets here or explicitly invoke a packaged generator.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
file=sys.stderr, flush=True
)
# Run the full bypass battery - raw LDAP/Kerberos may still reach the real DC
bypass_results = waf_bypass_full(ip, hostname=ip, waf_info=waf_info, timeout=timeout)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep WAF bypass attempts out of dry-run detection

When a host exposes at least two DC-signature ports and an HTTP WAF is detected, this call executes the full bypass battery even under --mode dry-run or --active-search off. That battery sends spoofed forwarding headers, obfuscated paths, TRACE requests, raw LDAP/Kerberos messages, and fragmented requests, contradicting the documented preview-only dry-run behavior and potentially triggering defenses; pass the execution mode into detection and run these bypass attempts only after active mode is explicitly selected.

Useful? React with 👍 / 👎.

Comment thread adpentest/core.py
print(f"[VERBOSE] [discover_email_servers] Detected Office365 service", file=sys.stderr, flush=True)

for mx_host, _ in mx_records:
for port in [25, 587, 465]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use TLS-aware probes for implicit-TLS mail ports

For MX servers exposing only implicit TLS, the discovery loops pass ports 465, 995, and 993 to plaintext SMTP, POP3, and IMAP helpers without enabling SSL. Those connections fail or time out even though the ports were already confirmed open, so secure-only mail deployments are reported as unresponsive and Exchange/email discovery becomes incomplete; use SMTP_SSL for 465 and set use_ssl=True for POP3S/IMAPS.

Useful? React with 👍 / 👎.

Comment thread publish_to_pypi.py
Comment on lines +68 to +69
for file in Path(".").rglob("*"):
if file.is_file() and not str(file).startswith("."):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict source distributions to declared project files

When this publisher is run from a working tree that has previously produced scan or lab artifacts, the recursive walk includes every ordinary non-dot file unless its path happens to contain one of the few skip strings. Generated files such as test-results-*.json, *_spns.txt, vulnerability reports, lab configuration, or other operator output can therefore be embedded in the sdist and uploaded publicly to PyPI, potentially disclosing targets, usernames, hashes, or credentials; build through the standard backend or use an explicit source-file allowlist/manifest.

Useful? React with 👍 / 👎.

Auto-install was effectively Debian-only on Linux: install_apt_tool assumed
apt-get and there was no fallback for dnf/yum/pacman/zypper systems.

- Add install_linux_tool(): try each available Linux package manager in order
  (apt/dnf/yum/pacman/zypper), with per-manager package-name overrides (e.g.
  samba-client on dnf/yum/zypper for smbclient) and a sudo prefix when non-root.
- auto_install_tool now uses install_linux_tool on Linux and falls back to pip
  when the OS package managers are exhausted. Windows keeps winget -> pip.

Verified: a missing binary (masscan) is installed end-to-end via apt-get and
resolved on PATH; package-name resolution is correct across managers; the
already-installed short-circuit still works.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
New adpentest/nmap_vuln_discovery.py: a heuristic engine that derives
candidate weaknesses from an nmap -sV + default,safe,vuln NSE scan (plus the
bundled AdPentestAI NSE scripts) instead of a fixed CVE catalog, so it can
surface novel/uncatalogued exposures.

Detectors: exposed management planes (RDP/VNC/WinRM/Redis/Mongo/...), cleartext
services (telnet/ftp/http/ldap/...), anonymous/null-session access, outdated
builds (by low major version or old embedded year), datastore-alongside-web
topology anomalies, and NSE vuln-script hits whose CVE ids are absent from the
framework catalog. Read-only; every finding is labeled a hypothesis requiring
validation, not a confirmed vulnerability.

Verified: py_compile passes; all detectors fire on synthetic nmap XML; the full
scan() pipeline runs end-to-end against localhost; module ships in the wheel.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
…ing (1.2.4)

Two bugs surfaced by a real dry-run scan report:

1. parallel_pentest_attempt documented a "all" technique but never implemented
   it, so every host failed with "Unknown technique: all" (0% success). Refactor
   the per-technique logic into _run_one() and add an "all" path that runs all
   five techniques per host and aggregates status, with per-technique detail.

2. is_usable_host let link-local/APIPA (169.254/16), reserved (255.255.255.255),
   and /24 network/broadcast (.0/.255) addresses through, so recon counted
   broadcast/APIPA noise as live hosts. Reject them; the DC and gateway are kept.

Bump version to 1.2.4.

Verified: junk addresses dropped while DC + gateway kept; technique="all" runs
all five techniques with no "Unknown technique" error; py_compile and twine
check pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
Resolve conflicts between main's hashcat/john/mimikatz integration and this
branch's 1.2.x work:
- AD_TOOLS / PIP_PACKAGES / EXECUTABLES: keep both the CVE scanners and the
  hash-cracking/credential-extraction tools.
- LDAP timeout: combine both fixes (connect_timeout on Server + receive_timeout
  on Connection).
- build_ad_command email discovery: keep this branch's _host-capture form.
- Version stays 1.2.4.

Verified: no conflict markers remain; py_compile and full import succeed; both
main and branch tool sets are present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LThPffiKTAzLRXmY6YpHEL
@netanelcyber
netanelcyber merged commit d6abf50 into main Sep 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants